home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Serious Software
/
Cherwell Scientific Demos
/
pro Fit
/
pro Fit 5.0 demo (fpu).sea
/
pro Fit 5.0 demo (fpu)
/
Functions & Programs
/
BlockChart
next >
Wrap
Text File
|
1996-06-02
|
7KB
|
223 lines
{ This program draws a three-dimensional block chart of a two-dimensional scalar }
{ field z(x,y). }
{ The x- and y-coordinates of the field correspond to column and row }
{ numbers. The z coordinate is given by the value in a given row/column. }
{ To use the program, choose "Add to Menu" from the Misc menu to compile it }
{ Then open a data window (if none is open). Then run the program by choosing }
{ "BlockChart" from the misc menu. }
program BlockChart;
{ First we define all the variables we need }
var dataWindID, drawWindID;
i, j;
nr, mean, med, min, max;
ph, pv, phh, pvv, thick, norm;
posH, posV; { absolute position }
totH, totV; { maximum width, height }
disH, disV; { distance between 2 bars }
phi, theta; { the angles of 3-D effect (phi is in plane) }
phi0, theta0; { the same in degrees }
fcol, lcol; { first and last column to be drawn }
frow, lrow; { first and last row to be drawn }
drawGrid; { draws the grid if not 0 }
color1, color2; { items in color menus to be selected }
colRED, colGREEN, colBLUE: array[1..12];
procedure Initialize;
{ This routine is called once when the program is added to }
{ pro Fit's menus. }
{ We use it to initialize several global variables. }
begin
posH := 220; posV := 100;
totH := 220; totV := 200;
thick := 10;
phi0 := 45;
theta0 := 30;
color1 := 2;
color2 := 7;
drawGrid := 1;
fcol := 1; lcol := 2;
frow := 1; lrow := 5;
{ The following is a color table. It could be easily extended if necessary. }
colRED[1] := 65535; colGREEN[1] := 0; colBLUE[1] := 65535; { magenta }
colRED[2] := 0; colGREEN[2] := 0; colBLUE[2] := 65535; { blue }
colRED[3] := 0; colGREEN[3] := 65535; colBLUE[3] := 65535; { cyan }
colRED[4] := 0; colGREEN[4] := 32767; colBLUE[4] := 8191; { dark green }
colRED[5] := 0; colGREEN[5] := 65535; colBLUE[5] := 0; { light green }
colRED[6] := 65535; colGREEN[6] := 65535; colBLUE[6] := 0; { yellow }
colRED[7] := 65535; colGREEN[7] := 32767; colBLUE[7] := 0; { orange }
colRED[8] := 65535; colGREEN[8] := 0; colBLUE[8] := 0; { red }
colRED[9] := 65535; colGREEN[9] := 65535; colBLUE[9] := 65535; { white }
colRED[10] := 49150; colGREEN[10] := 49150; colBLUE[10] := 49150; { light grey }
colRED[11] := 32767; colGREEN[11] := 32767; colBLUE[11] := 32767; { grey }
colRED[12] := 16383; colGREEN[12] := 16383; colBLUE[12] := 16383; { dark grey }
end;
{ We define a local procedure to set the different shades of color. }
procedure CalcSetFitColor(len,mode);
var thecolor, redC, blueC, greenC;
begin
if len < 0 then
thecolor := color2
else
thecolor := color1;
redC := colRED[thecolor]-mode*1000; if (redC < 0) then redC := 0;
greenC := colGREEN[thecolor]-mode*1000; if (greenC < 0) then greenC := 0;
blueC := colBLUE[thecolor]-mode*1000; if (blueC < 0) then blueC := 0;
SetFillColor(redC, greenC, blueC);
end;
{ This procedure does the mapping of 3-D coordinates onto the }
{ screen coordinates }
procedure Do3Dto2D(col, row, dep, hor, z, doline);
var alpha, radius, x, y;
begin
x := row*disH + hor;
y := col*disV + dep;
if x = 0 then
if y < 0 then
alpha := 1.5*π
else
alpha := π/2
else
alpha := arctan(y/x);
if x < 0 then
alpha := alpha + π;
alpha := alpha + phi;
radius := sqrt(x*x + y*y);
phh := posH + radius*cos(alpha);
pvv := posV + radius*sin(alpha)*sin(theta) - z*cos(theta);
if doline then
LineTo(phh, pvv)
else
MoveTo(phh, pvv);
end;
{ Draws all negative or all positive bars, depending on the parameter sign. }
procedure DrawCharts(sign);
var len;
begin
SetFillPattern(2); { full color }
for i:= fcol to lcol do
begin
GroupBegin;
for j:= frow to lrow do
if dataOK(j,i) then
begin
len := data[j,i] * norm;
if ((len < 0) and (sign < 0)) or ((len >= 0) and (sign > 0)) then
begin
CalcSetFitColor(len,0);
Do3Dto2D(i-fcol, j-frow, thick, thick, 0, 0);
OpenPoly(0, true);
Do3Dto2D(i-fcol, j-frow, thick, -thick, 0, 1);
Do3Dto2D(i-fcol, j-frow, thick, -thick, len, 1);
Do3Dto2D(i-fcol, j-frow, thick, thick, len, 1);
ClosePoly;
CalcSetFitColor(len,20);
Do3Dto2D(i-fcol, j-frow, thick, thick, 0, 0);
OpenPoly(0, true);
Do3Dto2D(i-fcol, j-frow, -thick, thick, 0, 1);
Do3Dto2D(i-fcol, j-frow, -thick, thick, len, 1);
Do3Dto2D(i-fcol, j-frow, thick, thick, len, 1);
ClosePoly;
CalcSetFitColor(len,5);
if len < 0 then
len := 0;
Do3Dto2D(i-fcol, j-frow, thick, thick, len, 0);
OpenPoly(0, true);
Do3Dto2D(i-fcol, j-frow, thick, -thick, len, 1);
Do3Dto2D(i-fcol, j-frow, -thick, -thick, len, 1);
Do3Dto2D(i-fcol, j-frow, -thick, thick, len, 1);
ClosePoly;
end;
end;
GroupEnd;
end;
end;
{ Draws a line grid at value 0. }
procedure DrawTheGrid;
begin
GroupBegin;
for i:= fcol to lcol do
begin
Do3Dto2D(i-fcol, 0, 0, 0, 0, 0);
Do3Dto2D(i-fcol, lrow-frow, 0, 0, 0, 1);
end;
for j:= frow to lrow do
begin
Do3Dto2D(0, j-frow, 0, 0, 0, 0);
Do3Dto2D(lcol-fcol, j-frow, 0, 0, 0, 1);
end;
GroupEnd;
end;
{ Main program }
begin
dataWindID := GetCurrentWindow(dataType); { check for a data window }
if (dataWindID = 0) then
begin
Alert('There is no data to be drawn.');
Halt;
end;
drawWindID := FrontmostWindow(drawingType); { check for a drawing window }
if (drawWindID = 0) then
begin
NewWindow(drawingType); { open a new one if necessary }
drawWindID := FrontmostWindow(drawingType);
if (drawWindID = 0) then
begin
Alert('Could not open a new drawing window.');
Halt;
end;
end
else
BringWindowToFront(drawWindID);
Input('$CFirst column', fcol, '$CLast column', lcol,
'First row', frow, 'Last row', lrow,
'$Pmagenta;blue;cyan;dark green;light green;yellow;orange;red;white;light gray;gray;dark gray$Color if positive', color1,
'$Pmagenta;blue;cyan;dark green;light green;yellow;orange;red;white;light gray;gray;dark gray$Color if negative', color2);
if (lrow <= frow) then
disH := totH
else
disH := totH / (lrow - frow);
if (lcol <= fcol) then
disV := totV
else
disV := totV / (lcol - fcol);
Input('Rotation angle', phi0, 'Slant angle', theta0, 'Thickness', thick, '$XDraw line grid', drawGrid);
phi := phi0*π/180;
theta := theta0*π/180;
if phi > π then phi := π/2;
if phi < 0 then phi := 0;
if theta > π then theta := π/3;
if theta < 0 then theta := 0;
SelectCells(fcol, frow, lcol, lrow);
if CalcStat(0,true,true,false,true) then { calculate the maximum and minimum }
begin
GetMedian(nr,mean,med,min,max);
norm := 120; { normalize the height of the bars }
if -min > max then
norm := -norm/min
else
norm := norm/max;
SetLineColor(0, 0, 0); { start drawing }
GroupBegin;
DrawCharts(-1);
if drawGrid then
DrawTheGrid;
DrawCharts(1);
GroupEnd;
end
else
Alert('Statistical preparation failed.');
end;